/**
 @file sys_usw_dmps.h

 @author  Copyright (C) 2018 Centec Networks Inc.  All rights reserved.

 @date 2018-09-12

 @version v2.0

*/

#ifndef _SYS_USW_DMPS_H
#define _SYS_USW_DMPS_H
#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_port.h"

/****************************************************************
*
* Defines and Macros
*
****************************************************************/
#define SYS_DMPS_INVALID_CHAN_ID  0xFFFF
#define SYS_DMPS_INVALID_SUB_CHAN_ID  0xFFFF
#define SYS_DMPS_INVALID_U8   0xff
#define SYS_DMPS_INVALID_U16  0xffff
#define SYS_DMPS_INVALID_U32  0xffffffff

#define SYS_DMPS_LOOP_SUB_CHAN 25
#define SYS_DMPS_MISC_SUB_CHAN 24

#define SYS_DMPS_MAX_SERDES_NUM_PER_PORT 8


#define SYS_DMPS_CL37_ANMODE_MAX 8

#define SYS_SCALE_FACTOR    1000

#define SELF_CHECK_VALUE_NO_USE 0
#define SELF_CHECK_STR_NO_USE "\0"

#define SYS_DMPS_DBG_OUT(level, FMT, ...) \
    do { \
        CTC_DEBUG_OUT(port, dmps, DMPS_SYS, level, FMT, ##__VA_ARGS__); \
    } while (0)
#define MCHIP_DMPS_CB(cb_function, lchip, ...)\
    do {\
        if(MCHIP_DMPS(lchip)->cb_function)\
        {\
            CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->cb_function(lchip, ##__VA_ARGS__));\
        }\
        else return CTC_E_INVALID_PTR;\
    } while (0)

#define SELF_CHECK_ERROR_FILTER(op, value)\
    do {\
        if(op < 0)\
        {\
            uint8 bit_len,i;\
            bit_len = 8 * sizeof(value);\
            for (i = 0; i < bit_len; i++)\
            {\
                value |= 1 << i;\
            }\
        }\
    } while (0)

#define SELF_CHECK_PRINT_FORMAT(type, value_check, invalid_value, uint_print, string_print)\
    do {\
        if(invalid_value == value_check)\
        {\
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-24s: %s\n", type, "-");\
            break;\
        }\
        if(sal_strlen(string_print))\
        {\
            if(24 >= sal_strlen(type))\
            {\
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-24s: %s\n", type, string_print);\
            }\
            else\
            {\
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "'%s' strlen is %zu,exceeds type_print_length\n",\
                    type, sal_strlen(string_print));\
                return CTC_E_INVALID_PARAM;\
            }\
        }\
        else\
        {\
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "    %-24s: %u\n", type, uint_print);\
        }\
    } while (0)

#define SELF_CHECK_SERDES_ITEM_PRINT_FORMAT(FMT_UINT, uint_print, FMT_STR, string_print, value_check, invalid_value)\
    do {\
        if(invalid_value == value_check)\
        {\
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, FMT_STR, "-");\
            break;\
        }\
        if(sal_strlen(string_print))\
        {\
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, FMT_STR, string_print);\
        }\
        else\
        {\
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, FMT_UINT, uint_print);\
        }\
    } while (0)
    
#define SELF_CHECK_SPACE_PRINT_CALC(remaining_length, check_value, invalid_value, uint_print, str_print)\
    do {\
        if(invalid_value == check_value)\
        {\
            remaining_length -= 1;\
            break;\
        }\
        if(sal_strlen(str_print))\
        {\
            remaining_length -= sal_strlen(str_print);\
        }\
        else\
        {\
            int8 bit_length = 1;\
            uint32 tmp_val = (uint32)uint_print;\
            for(; bit_length < 11; bit_length++)\
            {\
                tmp_val /= 10;\
                if(0 == tmp_val)\
                {\
                    remaining_length -= bit_length;\
                    break;\
                }\
            }\
            if(11 == bit_length)\
            {\
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "\nError happens, print_val %u exceeds 10^10\n", uint_print);\
                return CTC_E_INVALID_PARAM;\
            }\
        }\
    }while (0)
    
#define SELF_CHECK_SPACE_PRINT(length)\
    do {\
        if(length < 0)\
        {\
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "self_check item print length exceeds threshold given\n");\
            return CTC_E_INVALID_PARAM;\
        }\
        for(; length > 0; length--)\
        {\
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s", " ");\
        }\
    }while (0)

#define SYS_SERDES_MODE_SUPPORT_PAR_DET(serdes_mode) ((CTC_CHIP_SERDES_QSGMII_MODE == serdes_mode) || \
    (CTC_CHIP_SERDES_SGMII_MODE == serdes_mode) || (CTC_CHIP_SERDES_2DOT5G_MODE == serdes_mode))

enum sys_dmps_pcs_module_e
{
    SHAREDPCS,  /*SGMII & 2500BASE-X*/
    USXGMIIPCS, /*USXGMII*/
    USGMIIPCS,  /*O-USGMII & Q-USGMII*/

    SYS_DMPS_MAX_PCS_MODULE
};
typedef enum sys_dmps_pcs_module_e sys_dmps_pcs_module_t;

#define SYS_DMPS_GET_SERDES_MODE_BY_IFMODE(speed, iftype, mode)  \
do \
{\
    uint8 speed_nml = (uint8)speed; \
    if ((SYS_PORT_SPEED_1G == speed_nml) && (CTC_PORT_IF_SGMII == iftype))    mode = CTC_CHIP_SERDES_SGMII_MODE;     \
    else if ((SYS_PORT_SPEED_10G == speed_nml) && ((CTC_PORT_IF_XFI == iftype) || \
                                                (CTC_PORT_IF_CR == iftype) || \
                                                (CTC_PORT_IF_KR == iftype)))     mode = CTC_CHIP_SERDES_XFI_MODE;    \
    else if ((SYS_PORT_SPEED_2G5 == speed_nml) && (CTC_PORT_IF_2500X == iftype))   mode = CTC_CHIP_SERDES_2DOT5G_MODE;    \
    else if ((SYS_PORT_SPEED_40G == speed_nml) && (CTC_PORT_IF_CR4 == iftype))     mode = CTC_CHIP_SERDES_XLG_MODE;       \
    else if ((SYS_PORT_SPEED_40G == speed_nml) && (CTC_PORT_IF_KR4 == iftype))     mode = CTC_CHIP_SERDES_XLG_MODE;       \
    else if ((SYS_PORT_SPEED_40G == speed_nml) && (CTC_PORT_IF_CR2 == iftype))     mode = CTC_CHIP_SERDES_XLG_R2_MODE;    \
    else if ((SYS_PORT_SPEED_40G == speed_nml) && (CTC_PORT_IF_KR2 == iftype))     mode = CTC_CHIP_SERDES_XLG_R2_MODE;    \
    else if ((SYS_PORT_SPEED_40G == speed_nml) && (CTC_PORT_IF_CR == iftype))      mode = CTC_CHIP_SERDES_XLG_R1_MODE;    \
    else if ((SYS_PORT_SPEED_40G == speed_nml) && (CTC_PORT_IF_KR == iftype))      mode = CTC_CHIP_SERDES_XLG_R1_MODE;    \
    else if ((SYS_PORT_SPEED_100G == speed_nml) && (CTC_PORT_IF_CR4 == iftype))    mode = CTC_CHIP_SERDES_CG_MODE;        \
    else if ((SYS_PORT_SPEED_100G == speed_nml) && (CTC_PORT_IF_KR4 == iftype))    mode = CTC_CHIP_SERDES_CG_MODE;        \
    else if ((SYS_PORT_SPEED_100G == speed_nml) && (CTC_PORT_IF_CR2 == iftype))    mode = CTC_CHIP_SERDES_CG_R2_MODE;     \
    else if ((SYS_PORT_SPEED_100G == speed_nml) && (CTC_PORT_IF_KR2 == iftype))    mode = CTC_CHIP_SERDES_CG_R2_MODE;     \
    else if ((SYS_PORT_SPEED_25G == speed_nml) && (CTC_PORT_IF_CR == iftype))      mode = CTC_CHIP_SERDES_XXVG_MODE;      \
    else if ((SYS_PORT_SPEED_25G == speed_nml) && (CTC_PORT_IF_KR == iftype))      mode = CTC_CHIP_SERDES_XXVG_MODE;      \
    else if ((SYS_PORT_SPEED_50G == speed_nml) && (CTC_PORT_IF_CR2 == iftype))     mode = CTC_CHIP_SERDES_LG_MODE;        \
    else if ((SYS_PORT_SPEED_50G == speed_nml) && (CTC_PORT_IF_KR2 == iftype))     mode = CTC_CHIP_SERDES_LG_MODE;        \
    else if ((SYS_PORT_SPEED_50G == speed_nml) && (CTC_PORT_IF_CR == iftype))      mode = CTC_CHIP_SERDES_LG_R1_MODE;     \
    else if ((SYS_PORT_SPEED_50G == speed_nml) && (CTC_PORT_IF_KR == iftype))      mode = CTC_CHIP_SERDES_LG_R1_MODE;     \
    else if ((SYS_PORT_SPEED_200G == speed_nml) && (CTC_PORT_IF_CR4 == iftype))    mode = CTC_CHIP_SERDES_CCG_R4_MODE;    \
    else if ((SYS_PORT_SPEED_200G == speed_nml) && (CTC_PORT_IF_KR4 == iftype))    mode = CTC_CHIP_SERDES_CCG_R4_MODE;    \
    else if ((SYS_PORT_SPEED_400G == speed_nml) && (CTC_PORT_IF_CR8 == iftype))    mode = CTC_CHIP_SERDES_CDG_R8_MODE;    \
    else if ((SYS_PORT_SPEED_400G == speed_nml) && (CTC_PORT_IF_KR8 == iftype))    mode = CTC_CHIP_SERDES_CDG_R8_MODE;    \
    else if ((SYS_PORT_SPEED_100G == speed_nml) && (CTC_PORT_IF_CR == iftype))     mode = CTC_CHIP_SERDES_CG_R1_MODE;     \
    else if ((SYS_PORT_SPEED_100G == speed_nml) && (CTC_PORT_IF_KR == iftype))     mode = CTC_CHIP_SERDES_CG_R1_MODE;     \
    else if ((SYS_PORT_SPEED_200G == speed_nml) && (CTC_PORT_IF_CR2 == iftype))    mode = CTC_CHIP_SERDES_CCG_R2_MODE;    \
    else if ((SYS_PORT_SPEED_200G == speed_nml) && (CTC_PORT_IF_KR2 == iftype))    mode = CTC_CHIP_SERDES_CCG_R2_MODE;    \
    else if ((SYS_PORT_SPEED_400G == speed_nml) && (CTC_PORT_IF_CR4 == iftype))    mode = CTC_CHIP_SERDES_CDG_R4_MODE;    \
    else if ((SYS_PORT_SPEED_400G == speed_nml) && (CTC_PORT_IF_KR4 == iftype))    mode = CTC_CHIP_SERDES_CDG_R4_MODE;    \
    else if ((SYS_PORT_SPEED_800G == speed_nml) && (CTC_PORT_IF_CR8 == iftype))    mode = CTC_CHIP_SERDES_DCCCG_R8_MODE;  \
    else if ((SYS_PORT_SPEED_800G == speed_nml) && (CTC_PORT_IF_KR8 == iftype))    mode = CTC_CHIP_SERDES_DCCCG_R8_MODE;  \
    else                                                                       mode = CTC_CHIP_MAX_SERDES_MODE;       \
}while(0)

#define SYS_DMPS_GET_IFMODE_BY_SERDES_MODE(speed, iftype, mode)  \
do \
{\
    if(mode == CTC_CHIP_SERDES_SGMII_MODE) {speed = SYS_PORT_SPEED_1G; iftype = CTC_PORT_IF_SGMII;}    \
    else if(mode == CTC_CHIP_SERDES_XFI_MODE) {speed = SYS_PORT_SPEED_10G; iftype = CTC_PORT_IF_XFI;}   \
    else if(mode == CTC_CHIP_SERDES_2DOT5G_MODE) {speed = SYS_PORT_SPEED_2G5; iftype = CTC_PORT_IF_2500X;}   \
    else if(mode == CTC_CHIP_SERDES_XLG_MODE) {speed = SYS_PORT_SPEED_40G; iftype = CTC_PORT_IF_CR4;}      \
    else if(mode == CTC_CHIP_SERDES_CG_MODE) {speed = SYS_PORT_SPEED_100G; iftype = CTC_PORT_IF_CR4;}       \
    else if(mode == CTC_CHIP_SERDES_CG_R2_MODE) {speed = SYS_PORT_SPEED_100G; iftype = CTC_PORT_IF_CR2;}    \
    else if(mode == CTC_CHIP_SERDES_XXVG_MODE) {speed = SYS_PORT_SPEED_25G; iftype = CTC_PORT_IF_CR;}     \
    else if(mode == CTC_CHIP_SERDES_LG_MODE) {speed = SYS_PORT_SPEED_50G; iftype = CTC_PORT_IF_CR2;}       \
    else if(mode == CTC_CHIP_SERDES_LG_R1_MODE) {speed = SYS_PORT_SPEED_50G; iftype = CTC_PORT_IF_CR;}    \
    else if(mode == CTC_CHIP_SERDES_CCG_R4_MODE) {speed = SYS_PORT_SPEED_200G; iftype = CTC_PORT_IF_CR4;}   \
    else if(mode == CTC_CHIP_SERDES_CDG_R8_MODE) {speed = SYS_PORT_SPEED_400G; iftype =CTC_PORT_IF_CR8;}   \
    else if(mode == CTC_CHIP_SERDES_CG_R1_MODE) {speed = SYS_PORT_SPEED_100G; iftype = CTC_PORT_IF_CR;}    \
    else if(mode == CTC_CHIP_SERDES_CCG_R2_MODE) {speed = SYS_PORT_SPEED_200G; iftype = CTC_PORT_IF_CR2;}   \
    else if(mode == CTC_CHIP_SERDES_CDG_R4_MODE) {speed = SYS_PORT_SPEED_400G; iftype = CTC_PORT_IF_CR4;}   \
    else if(mode == CTC_CHIP_SERDES_DCCCG_R8_MODE) {speed = SYS_PORT_SPEED_800G; iftype = CTC_PORT_IF_CR8;} \
    else if(mode == CTC_CHIP_SERDES_XLG_R2_MODE) {speed = SYS_PORT_SPEED_40G; iftype = CTC_PORT_IF_CR2;} \
    else if(mode == CTC_CHIP_SERDES_XLG_R1_MODE) {speed = SYS_PORT_SPEED_40G; iftype = CTC_PORT_IF_CR;} \
}while(0)

#define SYS_DMPS_GET_PORT_SPEED(mode, speed)  do\
{\
    if (CTC_CHIP_SERDES_SGMII_MODE == mode)          { speed = SYS_PORT_SPEED_1G;  } \
    else if (CTC_CHIP_SERDES_XFI_MODE == mode)       { speed = SYS_PORT_SPEED_10G; } \
    else if (CTC_CHIP_SERDES_2DOT5G_MODE == mode)    { speed = SYS_PORT_SPEED_2G5; } \
    else if (CTC_CHIP_SERDES_XLG_MODE == mode)       { speed = SYS_PORT_SPEED_40G; } \
    else if (CTC_CHIP_SERDES_XLG_R2_MODE == mode)    { speed = SYS_PORT_SPEED_40G; } \
    else if (CTC_CHIP_SERDES_XLG_R1_MODE == mode)    { speed = SYS_PORT_SPEED_40G; } \
    else if (CTC_CHIP_SERDES_CG_MODE == mode)        { speed = SYS_PORT_SPEED_100G;} \
    else if (CTC_CHIP_SERDES_XXVG_MODE == mode)      { speed = SYS_PORT_SPEED_25G; } \
    else if (CTC_CHIP_SERDES_LG_MODE == mode)        { speed = SYS_PORT_SPEED_50G; } \
    else if (CTC_CHIP_SERDES_LG_R1_MODE == mode)     { speed = SYS_PORT_SPEED_50G; } \
    else if (CTC_CHIP_SERDES_CG_R2_MODE == mode)     { speed = SYS_PORT_SPEED_100G;} \
    else if (CTC_CHIP_SERDES_CCG_R4_MODE == mode)    { speed = SYS_PORT_SPEED_200G;} \
    else if (CTC_CHIP_SERDES_CDG_R8_MODE == mode)    { speed = SYS_PORT_SPEED_400G;} \
    else if (CTC_CHIP_SERDES_CG_R1_MODE == mode)     { speed = SYS_PORT_SPEED_100G;} \
    else if (CTC_CHIP_SERDES_CCG_R2_MODE == mode)    { speed = SYS_PORT_SPEED_200G;} \
    else if (CTC_CHIP_SERDES_CDG_R4_MODE == mode)    { speed = SYS_PORT_SPEED_400G;} \
    else if (CTC_CHIP_SERDES_DCCCG_R8_MODE == mode)  { speed = SYS_PORT_SPEED_800G;} \
    else                                             { speed = SYS_PORT_SPEED_MAX; } \
}while(0)

#define SYS_DMPS_IS_PAM4_MODE(mode) ((CTC_CHIP_SERDES_LG_R1_MODE == mode) \
                                    || (CTC_CHIP_SERDES_XLG_R1_MODE == mode)\
                                    || (CTC_CHIP_SERDES_CG_R2_MODE == mode) \
                                    || (CTC_CHIP_SERDES_CCG_R4_MODE == mode) \
                                    || (CTC_CHIP_SERDES_CDG_R8_MODE == mode) \
                                    || (CTC_CHIP_SERDES_CG_R1_MODE == mode) \
                                    || (CTC_CHIP_SERDES_CCG_R2_MODE == mode) \
                                    || (CTC_CHIP_SERDES_CDG_R4_MODE == mode) \
                                    || (CTC_CHIP_SERDES_DCCCG_R8_MODE == mode))

#define SYS_DMPS_GET_SERDES_NUM_BY_MODE(mode, serdes_num) \
do {\
    switch(mode)\
    {\
        case CTC_CHIP_SERDES_LG_MODE:\
        case CTC_CHIP_SERDES_CG_R2_MODE:\
        case CTC_CHIP_SERDES_CCG_R2_MODE:\
        case CTC_CHIP_SERDES_XLG_R2_MODE:\
            serdes_num = 2;\
            break;\
        case CTC_CHIP_SERDES_XLG_MODE:\
        case CTC_CHIP_SERDES_CG_MODE:\
        case CTC_CHIP_SERDES_CCG_R4_MODE:\
        case CTC_CHIP_SERDES_CDG_R4_MODE:\
            serdes_num = 4;\
            break;\
        case CTC_CHIP_SERDES_CDG_R8_MODE:\
        case CTC_CHIP_SERDES_DCCCG_R8_MODE:\
            serdes_num = 8;\
            break;\
        case CTC_CHIP_SERDES_XFI_MODE:\
        case CTC_CHIP_SERDES_SGMII_MODE:\
        case CTC_CHIP_SERDES_QSGMII_MODE:\
        case CTC_CHIP_SERDES_2DOT5G_MODE:\
        case CTC_CHIP_SERDES_XXVG_MODE:\
        case CTC_CHIP_SERDES_LG_R1_MODE:\
        case CTC_CHIP_SERDES_XLG_R1_MODE:\
        case CTC_CHIP_SERDES_CG_R1_MODE:\
        case CTC_CHIP_SERDES_NONE_MODE:\
        default:\
            serdes_num = 1;\
            break;\
    }\
} while(0)
#define SYS_USW_DMPS_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

typedef int32 (* SYS_CALLBACK_DMPS_FUN_P)  (uint8 lchip, uint32 gport);

enum sys_dmps_lport_type_e
{
    SYS_DMPS_NETWORK_PORT,
    SYS_DMPS_OAM_PORT,
    SYS_DMPS_DMA_PORT,
    SYS_DMPS_ILOOP_PORT,
    SYS_DMPS_ELOOP_PORT,
    SYS_DMPS_WLANDEC_PORT,
    SYS_DMPS_WLANENC_PORT,
    SYS_DMPS_WLANREASSEMBLE_PORT,
    SYS_DMPS_MAC_DECRYPT_PORT,
    SYS_DMPS_MAC_ENCRYPT_PORT,
    SYS_DMPS_RSV_PORT,
    SYS_DMPS_CPU_MAC_PORT,  /*TMM*/
    SYS_DMPS_LOO_PORT,      /*TMM*/
    SYS_DMPS_MISC_OTHER_PORT,      /*TMM*/
    SYS_DMPS_INACTIVE_NETWORK_PORT,  /*TMM*/
    SYS_DMPS_CPUMAC_NETWORK_PORT,  /*TMM*/
    SYS_DMPS_ELOG_PORT,

    SYS_DMPS_MAX_PORT_TYPE
};
typedef enum sys_dmps_lport_type_e sys_dmps_lport_type_t;

enum sys_dmps_direction_e
{
    DMPS_RX,
    DMPS_TX,
    DMPS_DIR_BUTT
};
typedef enum sys_dmps_direction_e sys_dmps_direction_t;

enum sys_dmps_serdes_polarity_e
{
    DMPS_POLARITY_NORM, /*0 normal*/
    DMPS_POLARITY_INV,  /*1 reverse*/
    DMPS_POLARITY_BUTT
};
typedef enum sys_dmps_serdes_polarity_e sys_dmps_serdes_polarity_t;

enum sys_dmps_serdes_speed_e
{
    SERDES_SPEED_0G        = 0,          /* serdes_speed = 0,         ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
    SERDES_SPEED_1_25G     = 1,          /* serdes_speed = 1250000,   ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
    SERDES_SPEED_3_125G    = 2,          /* serdes_speed = 3125000,   ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
    SERDES_SPEED_10_3125G  = 3,          /* serdes_speed = 10312500,  ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
    SERDES_SPEED_11_40625G = 4,          /* serdes_speed = 11406250,  ock = CTC_CHIP_SERDES_OCS_MODE_11_06G */
    SERDES_SPEED_12_5G     = 5,          /* serdes_speed = 12500000,  ock = CTC_CHIP_SERDES_OCS_MODE_12_12G */
    SERDES_SPEED_12_96875G = 6,          /* serdes_speed = 12968750,  ock = CTC_CHIP_SERDES_OCS_MODE_12_58G */
    SERDES_SPEED_10_9375G  = 7,          /* serdes_speed = 10937500,  ock = CTC_CHIP_SERDES_OCS_MODE_10_6G */
    SERDES_SPEED_20_625G   = 8,          /* serdes_speed = 20625000,  ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
    SERDES_SPEED_25_78125G = 9,          /* serdes_speed = 25781250,  ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
    SERDES_SPEED_28_125G   = 10,         /* serdes_speed = 28125000,  ock = CTC_CHIP_SERDES_OCS_MODE_27_27G */
    SERDES_SPEED_26_5625G  = 11,         /* serdes_speed = 26562500,  ock = CTC_CHIP_SERDES_OCS_MODE_26_56G */
    SERDES_SPEED_27_34375G = 12,         /* serdes_speed = 27343750,  ock = CTC_CHIP_SERDES_OCS_MODE_26_52G */
    SERDES_SPEED_27_78125G = 13,         /* serdes_speed = 27781250,  ock = CTC_CHIP_SERDES_OCS_MODE_26_9G */
    SERDES_SPEED_37_5G     = 14,         /* serdes_speed = 37500000,  ock = CTC_CHIP_SERDES_OCS_MODE_36_36G */
    SERDES_SPEED_39_0625G  = 15,         /* serdes_speed = 39062500,  ock = CTC_CHIP_SERDES_OCS_MODE_36_76G */
    SERDES_SPEED_51_5625G  = 16,         /* serdes_speed = 51562500,  ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
    SERDES_SPEED_53_125G   = 17,         /* serdes_speed = 53125000,  ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
    SERDES_SPEED_56_25G    = 18,         /* serdes_speed = 56250000,  ock = CTC_CHIP_SERDES_OCS_MODE_52_94G */
    SERDES_SPEED_103_125G  = 19,         /* serdes_speed = 103125000, ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
    SERDES_SPEED_106_25G   = 20,         /* serdes_speed = 106250000, ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
    SERDES_SPEED_112_5G    = 21,         /* serdes_speed = 112500000, ock = CTC_CHIP_SERDES_OCS_MODE_105_88G */
    SERDES_SPEED_42_5G     = 22,         /* serdes_speed = 42500000,  ock = CTC_CHIP_SERDES_OCS_MODE_NONE */

    SERDES_SPEED_MAX,
};
typedef enum sys_dmps_serdes_speed_e sys_dmps_serdes_speed_t;

#define SYS_USW_SERDES_SPEED_2_VALUE(speed, value)   \
do {\
    switch (speed)   \
    {\
        case SERDES_SPEED_0G:    \
            value = 0; \
            break;  \
        case SERDES_SPEED_1_25G:    \
            value = 1250000; \
            break;  \
        case SERDES_SPEED_3_125G:    \
            value = 3125000; \
            break;  \
        case SERDES_SPEED_10_3125G:    \
            value = 10312500; \
            break;  \
        case SERDES_SPEED_11_40625G:    \
            value = 11406250; \
            break;  \
        case SERDES_SPEED_12_5G:    \
            value = 12500000; \
            break;  \
        case SERDES_SPEED_12_96875G:    \
            value = 12968750; \
            break;  \
        case SERDES_SPEED_10_9375G:    \
            value = 10937500; \
            break;  \
        case SERDES_SPEED_20_625G:    \
            value = 20625000; \
            break;  \
        case SERDES_SPEED_25_78125G:    \
            value = 25781250; \
            break;  \
        case SERDES_SPEED_28_125G:    \
            value = 28125000; \
            break;  \
        case SERDES_SPEED_26_5625G:    \
            value = 26562500; \
            break;  \
        case SERDES_SPEED_27_34375G:    \
            value = 27343750; \
            break;  \
        case SERDES_SPEED_27_78125G:    \
            value = 27781250; \
            break;  \
        case SERDES_SPEED_37_5G:    \
            value = 37500000; \
            break;  \
        case SERDES_SPEED_39_0625G:    \
            value = 39062500; \
            break;  \
        case SERDES_SPEED_42_5G:    \
            value = 42500000;   \
            break;  \
        case SERDES_SPEED_51_5625G:    \
            value = 51562500; \
            break;  \
        case SERDES_SPEED_53_125G:    \
            value = 53125000; \
            break;  \
        case SERDES_SPEED_56_25G:    \
            value = 56250000; \
            break;  \
        case SERDES_SPEED_103_125G:    \
            value = 103125000; \
            break;  \
        case SERDES_SPEED_106_25G:    \
            value = 106250000; \
            break;  \
        case SERDES_SPEED_112_5G:    \
            value = 112500000; \
            break;  \
        default:\
            value = 0;\
            break;\
    }\
} while(0)

#define SYS_USW_SERDES_VALUE_2_SPEED(value, speed)   \
do {\
    switch(value)   \
    {\
        case 1250000:    \
            speed = SERDES_SPEED_1_25G; \
            break;  \
        case 3125000:    \
            speed = SERDES_SPEED_3_125G; \
            break;  \
        case 10312500:    \
            speed = SERDES_SPEED_10_3125G; \
            break;  \
        case 11406250:    \
            speed = SERDES_SPEED_11_40625G; \
            break;  \
        case 12500000:    \
            speed = SERDES_SPEED_12_5G; \
            break;  \
        case 12968750:    \
            speed = SERDES_SPEED_12_96875G; \
            break;  \
        case 10937500:    \
            speed = SERDES_SPEED_10_9375G; \
            break;  \
        case 20625000:    \
            speed = SERDES_SPEED_20_625G; \
            break;  \
        case 25781250:    \
            speed = SERDES_SPEED_25_78125G; \
            break;  \
        case 28125000:    \
            speed = SERDES_SPEED_28_125G; \
            break;  \
        case 26562500:    \
            speed = SERDES_SPEED_26_5625G; \
            break;  \
        case 27343750:    \
            speed = SERDES_SPEED_27_34375G; \
            break;  \
        case 27781250:    \
            speed = SERDES_SPEED_27_78125G; \
            break;  \
        case 37500000:    \
            speed = SERDES_SPEED_37_5G; \
            break;  \
        case 39062500:    \
            speed = SERDES_SPEED_39_0625G; \
            break;  \
        case 42500000:    \
            speed = SERDES_SPEED_42_5G;   \
            break;  \
        case 51562500:    \
            speed = SERDES_SPEED_51_5625G; \
            break;  \
        case 53125000:    \
            speed = SERDES_SPEED_53_125G; \
            break;  \
        case 56250000:    \
            speed = SERDES_SPEED_56_25G; \
            break;  \
        case 103125000:    \
            speed = SERDES_SPEED_103_125G; \
            break;  \
        case 106250000:    \
            speed = SERDES_SPEED_106_25G; \
            break;  \
        case 112500000:    \
            speed = SERDES_SPEED_112_5G; \
            break;  \
        case 0:    \
        default:\
            speed = SERDES_SPEED_0G; \
            break;  \
    }\
} while(0)

#define DMPS_MSG_REGISTER_RX_CB(lchip, msg_type, recv_cb)   CTC_ERROR_RETURN(_sys_usw_dmps_msg_register_rx_cb(lchip, msg_type, 0, recv_cb))
#define DMPS_MSG_REGISTER_RX_CB_NZ(lchip, msg_type, rps_data_size, recv_cb)   CTC_ERROR_RETURN(_sys_usw_dmps_msg_register_rx_cb(lchip, msg_type, rps_data_size, recv_cb))
#define DMPS_MSG_REGISTER_TX_PRI(lchip, msg_type, priority) CTC_ERROR_RETURN(_sys_usw_dmps_msg_register_tx_pri(lchip, msg_type, priority))

#define SYS_USW_DMPS_IS_OLD_DB(lchip) (DRV_IS_DUET2(lchip) || DRV_IS_TSINGMA(lchip) || DRV_IS_TMM(lchip))

/* ctc_port_speed_t to sys_port_speed_t*/
enum sys_port_speed_e
{
    SYS_PORT_SPEED_1G       = CTC_PORT_SPEED_1G,     /**< [GB.GG.D2.TM.TMM.TMA.AT] Port speed 1G mode*/
    SYS_PORT_SPEED_100M     = CTC_PORT_SPEED_100M,   /**< [GB.GG.D2.TM.TMM.TMA.AT] Port speed 100M mode*/
    SYS_PORT_SPEED_10M      = CTC_PORT_SPEED_10M,    /**< [GB.GG.D2.TM.TMM.TMA.AT] Port speed 10M mode*/
    SYS_PORT_SPEED_2G5      = CTC_PORT_SPEED_2G5,    /**< [GB.GG.D2.TM.TMM.AT] Port speed 2.5G mode*/
    SYS_PORT_SPEED_10G      = CTC_PORT_SPEED_10G,    /**< [GB.GG.D2.TM.TMM.AT] Port speed 10G mode*/
    SYS_PORT_SPEED_20G      = CTC_PORT_SPEED_20G,    /**< [GG.D2.TM] Port speed 20G mode*/
    SYS_PORT_SPEED_40G      = CTC_PORT_SPEED_40G,    /**< [GG.D2.TM.TMM.AT] Port speed 40G mode*/
    SYS_PORT_SPEED_100G     = CTC_PORT_SPEED_100G,   /**< [GG.D2.TM.TMM.AT] Port speed 100G mode*/
    SYS_PORT_SPEED_5G       = CTC_PORT_SPEED_5G,     /**< [D2.TM] Port speed 5G mode*/
    SYS_PORT_SPEED_25G      = CTC_PORT_SPEED_25G,    /**< [D2.TM.TMM.AT] Port speed 25G mode*/
    SYS_PORT_SPEED_50G      = CTC_PORT_SPEED_50G,    /**< [D2.TM.TMM.AT] Port speed 50G mode*/
    SYS_PORT_SPEED_200G     = CTC_PORT_SPEED_200G,   /**< [TMM.AT] Port speed 200G mode*/
    SYS_PORT_SPEED_400G     = CTC_PORT_SPEED_400G,   /**< [TMM.AT] Port speed 400G mode*/
    SYS_PORT_SPEED_800G     = CTC_PORT_SPEED_800G,   /**< [AT] Port speed 800G mode*/
    SYS_PORT_SPEED_300G,                            /**< [AT] Port speed 300G mode*/
    SYS_PORT_SPEED_MAX
};
typedef enum sys_port_speed_e sys_port_speed_t;

enum sys_usw_dmps_fec_type_e
{
    SYS_DMPS_FEC_TYPE_NONE,          /**< [Arctic] FEC OFF */
    SYS_DMPS_FEC_TYPE_RS528,         /**< [Arctic] RS(528,514) */
    SYS_DMPS_FEC_TYPE_RS544,         /**< [Arctic] RS(544,514) */
    SYS_DMPS_FEC_TYPE_RS272,         /**< [Arctic] RS(272,257) */
    SYS_DMPS_FEC_TYPE_FC2112,        /**< [Arctic] FC(2112,2080) */
    SYS_DMPS_FEC_TYPE_RS544INT,      /**< [Arctic] RS(544,514)-Int, only for 100GR1 */
    SYS_DMPS_FEC_TYPE_RS272INT,      /**< [Arctic] RS(272,257)-Int, only for 100GR1 */
    SYS_DMPS_FEC_TYPE_MAX
};
typedef enum sys_usw_dmps_fec_type_e sys_usw_dmps_fec_type_t;

enum sys_usw_dmps_mode_with_fec_e
{
    DMPS_XFI_NONE,
    DMPS_XFI_FC2112,
    DMPS_XXVG_NONE,
    DMPS_XXVG_FC2112,
    DMPS_XXVG_RS528,
    DMPS_XLG_NONE,
    DMPS_XLG_FC2112,
    DMPS_LG_R2_NONE,
    DMPS_LG_R2_RS528,
    DMPS_LG_R2_RS544,
    DMPS_LG_R1_NONE,
    DMPS_LG_R1_RS528,
    DMPS_LG_R1_RS544,
    DMPS_LG_R1_RS272,
    DMPS_CG_R4_NONE,
    DMPS_CG_R4_RS528,
    DMPS_CG_R4_RS544,
    DMPS_CG_R2_NONE,
    DMPS_CG_R2_RS528,
    DMPS_CG_R2_RS544,
    DMPS_CG_R2_RS272,
    DMPS_CG_R1_RS544,
    DMPS_CG_R1_RS272,
    DMPS_CG_R1_RS544INT,
    DMPS_CG_R1_RS272INT,
    DMPS_CCG_R4_RS544,
    DMPS_CCG_R4_RS272,
    DMPS_CCG_R2_RS544,
    DMPS_CCG_R2_RS272,
    DMPS_CDG_R8_RS544,
    DMPS_CDG_R8_RS272,
    DMPS_CDG_R4_RS544,
    DMPS_CDG_R4_RS272,
    DMPS_DCCCG_R8_RS544,
    DMPS_DCCCG_R8_RS272,
    DMPS_NONE_NONE,
    DMPS_MAX_MODE_FEC
};
typedef enum sys_usw_dmps_mode_with_fec_e sys_usw_dmps_mode_with_fec_t;

struct sys_usw_dmps_serdes_fw_version_s
{
    uint32 v_major;
    uint32 v_minor;
    uint32 v_patch;
    uint32 v_build;
};
typedef struct sys_usw_dmps_serdes_fw_version_s sys_usw_dmps_serdes_fw_version_t;

struct sys_dmps_serdes_self_check_info_s
{
    uint32 group_pll_lock             :2;
    uint32 lane_tx_pll_lock           :2;
    uint32 lane_rx_pll_lock           :2;
    uint32 sig_det                    :2;
    uint32 force_sig_det_en           :2;
    uint32 force_sig_det_val          :2;
    uint32 rx_rdy                     :2;
    uint32 cdr_det_en                 :2;
    uint32 cdr_lock                   :2;
    uint32 tx_lane_en                 :2;
    uint32 rx_lane_en                 :2;
    uint32 tx_prbs_en                 :2;
    uint32 rx_prbs_en                 :2;
    uint32 rx_ffe_en                  :2;
    uint32 rx_ctle_en                 :2;
    uint32 rx_dfe_en                  :2;
    uint8  lane_speed;          /*sys_dmps_serdes_speed_t*/
    uint8  lpbk_mode;           /*sys_usw_dmps_lpbk_en_type_t*/
    uint8  tx_train_stat;       /*sys_port_cl72_status_t*/
    uint8  rx_train_stat;       /*sys_port_cl72_status_t*/
    uint8  fw_stat;
    uint8  tx_prbs_pat;         /*sys_dmps_serdes_test_pattern_t*/
    uint8  rx_prbs_pat;         /*sys_dmps_serdes_test_pattern_t*/
    uint8  anlt_state;          /*sys_dmps_anlt_sm_state_type_t*/
    uint32 eye_height;
    uint32 eye_width;
    uint32 sig_det_thrd;
    uint32 rx_prbs_cnt;
    uint32 snr;
    ctc_chip_serdes_ctle_t rx_ctle;
    ctc_chip_serdes_ffe_t tx_eq;
    sys_usw_dmps_serdes_fw_version_t fw_ver;
    uint32 group_power_on             :2;
    uint32 lane_tx_power_on           :2;
    uint32 lane_rx_power_on           :2;
    uint32 tx_poly                    :2;
    uint32 rx_poly                    :2;
    uint32 rsv                        :22;
};
typedef struct sys_dmps_serdes_self_check_info_s sys_dmps_serdes_self_check_info_t;

struct sys_dmps_mac_self_check_info_s
{
    uint16 chip_frequency;
    uint16 lport;
    uint16 chan_id;
    uint16 mac_id;
    uint16 pcs_id;
    uint16 pcs_module;         /*sys_dmps_pcs_module_t*/
    uint16 logical_serdes[SYS_DMPS_MAX_SERDES_NUM_PER_PORT];
    uint16 physical_serdes[SYS_DMPS_MAX_SERDES_NUM_PER_PORT];
    uint16 user_serdes[SYS_DMPS_MAX_SERDES_NUM_PER_PORT];
    uint8  speed_mode;
    uint8  if_type;
    uint8  serdes_num;
    uint8  if_mode;
    uint32 fec_val;
    uint32 an_en                      :2;
    uint32 mac_en                     :2;
    uint32 mac_rx_pkt_en              :2;
    uint32 mac_tx_pkt_en              :2;
    uint32 preamble_length            :5;
    uint32 ipg_length                 :5;
    uint32 higig2_en                  :2;
    uint32 padding_en                 :2;
    uint32 check_crc_en               :2;
    uint32 strip_crc_en               :2;
    uint32 append_crc_en              :2;
    uint32 append_tod_en              :2;
    uint32 parallel_detect_en         :2;
    uint32 cl73_local_ability;
    uint32 cl73_fec;
    uint32 link_filter_length;
    uint32 fault_filter_length;
    uint32 link_mode;
    uint32 link_fsm;
    uint32 an_mode                    :4;
    uint32 pcs_link_intr_en           :2;
    uint32 unidir_en                  :2;
    uint32 tx_force_fault             :2;
    uint32 pcs_rx_rst                 :2;
    uint32 pcs_tx_rst                 :2;
    uint32 mii_rx_rst                 :2;
    uint32 mii_tx_rst                 :2;
    uint32 link_status                :2;
    uint32 link_status_raw            :2;
    uint32 local_fault                :2;
    uint32 remote_fault               :2;
    uint32 link_fault                 :2;
    uint32 pcs_sync                   :2;
    uint32 rx_block_lock              :2;
    uint16 bad_ber_cnt;
    uint16 err_blk_cnt;
    uint16 bip_err_cnt;
    uint16 code_err_cnt;
    uint32 correct_cnt;
    uint32 uncorrect_cnt;
    uint32 hi_ber                     :2;
    uint32 hi_ser                     :2;
    uint32 rx_am_lock                 :2;
    uint32 fec_am_lock                :2;
    uint32 xgfec_lock                 :2;
    uint32 rsfec_lock                 :2;
    uint32 rx_cwm_lock                :2;
    uint32 rsv                       :18;
    sys_dmps_serdes_self_check_info_t serdes_info[SYS_DMPS_MAX_SERDES_NUM_PER_PORT];
};
typedef struct sys_dmps_mac_self_check_info_s sys_dmps_mac_self_check_info_t;

struct sys_dmps_serdes_info_s
{
    uint16 serdes_id[8];
    uint8 serdes_mode;
    uint8 serdes_num;
};
typedef struct sys_dmps_serdes_info_s sys_dmps_serdes_info_t;

struct sys_dmps_flexe_phy_inst_s
{
    uint8  serdes_id;
    uint32 instance_id;
    uint8  dp_id;
    uint8  asic_inst_id[2];
};
typedef struct sys_dmps_flexe_phy_inst_s sys_dmps_flexe_phy_inst_t;

struct sys_dmps_flexe_phy_oh_sync_s
{
    uint32 enable;
    uint8  serdes_id;
};
typedef struct sys_dmps_flexe_phy_oh_sync_s sys_dmps_flexe_phy_oh_sync_t;

#define SYS_DATAPATH_DS_MAX_PORT_NUM     16
#define SYS_DATAPATH_DS_MAX_SERDES_NUM   8
#define SYS_DATAPATH_DS_MAX_CHAN_NUM   8

struct sys_dmps_change_chan_info_s
{
    uint8  dst_speed_mode;
    uint8  src_chan_num;
    uint8  dst_chan_num;

    uint16 src_chan_list[SYS_DATAPATH_DS_MAX_CHAN_NUM];
    uint16 dst_chan_list[SYS_DATAPATH_DS_MAX_CHAN_NUM];
};
typedef struct sys_dmps_change_chan_info_s sys_dmps_change_chan_info_t;

struct sys_dmps_ds_list_s
{
    uint8  ovclk;
    uint8  dst_mode;
    uint8  lsd_num;
    uint8  src_dport_num;
    uint8  dst_dport_num;

    uint16 lsd_list[SYS_DATAPATH_DS_MAX_SERDES_NUM];
    uint16 src_dport_list[SYS_DATAPATH_DS_MAX_PORT_NUM];
    uint16 dst_dport_list[SYS_DATAPATH_DS_MAX_PORT_NUM];
    sys_dmps_change_chan_info_t chan_info;
};
typedef struct sys_dmps_ds_list_s sys_dmps_ds_list_t;

struct sys_dmps_an_ability_s
{
    uint32 base_ability0;
    uint32 base_ability1;
    uint32 np0_ability0;
    uint32 np0_ability1;
    uint32 np1_ability0;
    uint32 np1_ability1;
};
typedef struct sys_dmps_an_ability_s sys_dmps_an_ability_t;


enum sys_dmps_anlt_sm_cfg_en_type_s
{
    SYS_DMPS_ANLT_SM_CFG_EN_TYPE_MAC = 0,     /* enable/disable MAC */
    SYS_DMPS_ANLT_SM_CFG_EN_TYPE_ANLT,
    SYS_DMPS_ANLT_SM_CFG_EN_TYPE_MAX,
};
typedef enum sys_dmps_anlt_sm_cfg_en_type_s sys_dmps_anlt_sm_cfg_en_type_t;

enum sys_dmps_anlt_sm_anlt_en_s
{
    SYS_DMPS_ANLT_SM_ANLT_DIS = 0,            /* enable/disable MAC */
    SYS_DMPS_ANLT_SM_ANLT_EN_CL73_AND_LT,
    SYS_DMPS_ANLT_SM_ANLT_EN_LT,
    SYS_DMPS_ANLT_SM_ANLT_MAX,
};
typedef enum sys_dmps_anlt_sm_anlt_en_s sys_dmps_anlt_sm_anlt_en_t;


enum sys_dmps_anlt_sm_state_type_s
{
    SYS_DMPS_ANLT_SM_STATE_IDLE = 0,          
    SYS_DMPS_ANLT_SM_STATE_AN_RUNNING,    
    SYS_DMPS_ANLT_SM_STATE_LT_RUNNING,
    SYS_DMPS_ANLT_SM_STATE_ANLT_DONE,
    SYS_DMPS_ANLT_SM_STATE_LINK_UP,
};
typedef enum sys_dmps_anlt_sm_state_type_s sys_dmps_anlt_sm_state_type_t;

enum sys_dmps_anlt_sm_status_msg_type_s
{
    DMPS_ANLT_SM_STATUS_MSG_TYPE_NONE  = 0,
    DMPS_ANLT_SM_STATUS_MSG_TYPE_AN_OK,
    DMPS_ANLT_SM_STATUS_MSG_TYPE_ANLT_OK,
    DMPS_ANLT_SM_STATUS_MSG_TYPE_LINK_UP_TIMEOUT,
    DMPS_ANLT_SM_STATUS_MSG_TYPE_RESTART_ANLT,
};
typedef enum sys_dmps_anlt_sm_status_msg_type_s sys_dmps_anlt_sm_status_msg_type_t;

enum sys_dmps_dynamic_switch_option_bitpos_s
{
    DMPS_DS_OPTION_SERDES_SWITCH = 0, /*0~skip serdes config in dymnaic switch  1~do serdes config in dymnaic switch*/
    DMPS_DS_OPTION_CLEAR_MAC,
    DMPS_DS_OPTION_CLEAR_CL73,
    DMPS_DS_OPTION_CLEAR_AN_FEC,
    DMPS_DS_OPTION_BIT_BUTT,
};
typedef enum sys_dmps_dynamic_switch_option_bitpos_s sys_dmps_dynamic_switch_option_bitpos_t;

struct sys_usw_dmps_mcu_msg_struct_s
{
    void *header;
    void *p_data;
};
typedef struct sys_usw_dmps_mcu_msg_struct_s sys_usw_dmps_mcu_msg_struct_t;

struct sys_usw_dmps_mcu_fw_version_s
{
    uint32 date;        /* build date */
    uint32 commit_id;   /* code commit id */
};
typedef struct sys_usw_dmps_mcu_fw_version_s sys_usw_dmps_mcu_fw_version_t;
enum sys_usw_dmps_msg_sync_status_s
{
    SYS_DMPS_MSG_SYNC_STATUS_IDLE = 0,
    SYS_DMPS_MSG_SYNC_STATUS_PROCESS,
};

enum sys_usw_dmps_msg_header_fields
{
    SYS_DMPS_MSG_HEADER_TYPE           = 0,
    SYS_DMPS_MSG_HEADER_ID                ,
    SYS_DMPS_MSG_HEADER_DATA_LEN          ,
    SYS_DMPS_MSG_HEADER_INVALID        = 0xff,
};

enum sys_usw_dmps_msg_buf_priority_s
{
    SYS_DMPS_MSG_BUF_PRIORITY_0   = 0,
    SYS_DMPS_MSG_BUF_PRIORITY_1,
    SYS_DMPS_MSG_BUF_PRIORITY_2,
    SYS_DMPS_MSG_BUF_PRIORITY_MAX,
};

enum sys_usw_dmps_msg_code_s
{
    /* C2M Sync Msg */
    SYS_DMPS_MSG_CODE_SYNC_C2M_ANLT_EN  = 0,      /* dmps_msg_ds_anlt_sm_en_t */
    SYS_DMPS_MSG_CODE_SYNC_C2M_ANLT_SM_OFF,       /* dmps_msg_ds_anlt_sm_en_t */
    SYS_DMPS_MSG_CODE_SYNC_C2M_RESTART_AN,        /* dmps_msg_ds_anlt_sm_en_t */
    SYS_DMPS_MSG_CODE_SYNC_C2M_AN_FEC,            /* dmps_msg_ds_sync_db_val_u8_t */
    SYS_DMPS_MSG_CODE_SYNC_C2M_DUMP_DB,           /* dmps_msg_ds_dump_mcu_db_t  */
    SYS_DMPS_MSG_CODE_SYNC_C2M_GET_MAC_STATS,     /* dmps_msg_ds_get_mac_stats_t */
    SYS_DMPS_MSG_CODE_SYNC_C2M_CLEAR_MAC_STATS,   /* dmps_msg_ds_clear_mac_stats_t */
    SYS_DMPS_MSG_CODE_SYNC_C2M_GET_ANLT_STATE,    /* uint32 */
    SYS_DMPS_MSG_CODE_SYNC_C2M_LINK_UP_INTR,      /* dmps_msg_ds_anlt_sm_en_t */
    SYS_DMPS_MSG_CODE_SYNC_C2M_ANLT_TIMER_EN,     /* dmps_msg_ds_anlt_sm_en_t */
    SYS_DMPS_MSG_CODE_SYNC_C2M_LINK_DOWN_INTR,    /* dmps_msg_ds_link_down_t */
    SYS_DMPS_MSG_CODE_SYNC_C2M_LINK_ADJUST,       /* dmps_msg_ds_anlt_sm_en_t */

    /* M2C Async Msg */
    SYS_DMPS_MSG_CODE_ASYNC_M2C_ANLT_STATUS_SYNC, /* dmps_msg_ds_anlt_status_sync_t */

    /* M2M Async Msg */
    SYS_DMPS_MSG_CODE_ASYNC_M2M_ANLT_INTR,        /* dmps_msg_ds_anlt_intr_info_t */
    SYS_DMPS_MSG_CODE_ASYNC_M2M_RESATRT_AN_TIMER_INTR, /* dmps_msg_ds_restart_an_timer_intr_info_t */
    SYS_DMPS_MSG_CODE_ASYNC_M2M_LINK_INTR,             /* dmps_msg_ds_link_intr_info_t */

    SYS_DMPS_MSG_CODE_MAX,       
};
typedef enum sys_usw_dmps_msg_code_s sys_usw_dmps_msg_code_t;

enum sys_usw_dmps_dyn_flag_e
{
    SYS_DMPS_DYN_BEFORE_CFG,
    SYS_DMPS_DYN_AFTER_CFG,

    SYS_DMPS_DYN_FLAG_MAX,     
};
typedef enum sys_usw_dmps_dyn_flag_e sys_usw_dmps_dyn_flag_t;

/****************************************************************************
 *
* DMPS MSG data_struct_s
*
*****************************************************************************/
struct dmps_msg_ds_anlt_sm_en_s
{
    uint32  speed;
    uint32  first_lsd      :16;
    uint32  timer_en       :1;
    uint32  rsv            :15;
};
typedef struct dmps_msg_ds_anlt_sm_en_s dmps_msg_ds_anlt_sm_en_t;

struct dmps_msg_ds_sync_an_fec_s
{
    uint32 first_lsd      :16;
    uint32 an_fec         :8;
    uint32 resv           :8;
};
typedef struct dmps_msg_ds_sync_an_fec_s  dmps_msg_ds_sync_an_fec_t;

struct dmps_msg_ds_anlt_status_sync_s
{
    uint32 dport    :16;
    uint32 status   :8;
    uint32 if_mode  :8;
    uint32 fec_type;
};
typedef struct dmps_msg_ds_anlt_status_sync_s dmps_msg_ds_anlt_status_sync_t;

struct dmps_msg_ds_dump_mcu_db_anlt_sm_s
{
    uint32 state       :3;
    uint32 anlt_en     :2;
    uint32 timer_type  :2;
    uint32 lt_done_bmp :8;
    uint32 event_cnt   :4;
    uint32 timer_en    :1;
    uint32 parameter   :8;
    uint32 res         :4;

    uint32 timeout_tick;
};
typedef struct dmps_msg_ds_dump_mcu_db_anlt_sm_s dmps_msg_ds_dump_mcu_db_anlt_sm_t;
struct dmps_msg_ds_dump_mcu_db_s
{
    uint32 mcu_id;
    uint32 anlt_sm_timeout;
    dmps_msg_ds_dump_mcu_db_anlt_sm_t   anlt_sm[8];
};
typedef struct dmps_msg_ds_dump_mcu_db_s dmps_msg_ds_dump_mcu_db_t;

struct  dmps_msg_ds_get_mac_stats_s
{
    uint32 stas_block_id  :8;
    uint32 resv           :24;
};
typedef struct dmps_msg_ds_get_mac_stats_s dmps_msg_ds_get_mac_stats_t;

struct dmps_msg_ds_clear_mac_stats_s
{
    uint32 stas_block_id  :8;
    uint32 dir            :1;
    uint32 resv           :23;
};
typedef struct dmps_msg_ds_clear_mac_stats_s dmps_msg_ds_clear_mac_stats_t; 

struct dmps_msg_ds_link_down_s
{
    uint32  first_lsd      :16;
    uint32  pcs_status     :1;
    uint32  rsv            :15;
};
typedef struct dmps_msg_ds_link_down_s dmps_msg_ds_link_down_t; 

/*mac statistics type*/
enum sys_stats_mac_rec_stats_type_e
{
    SYS_STATS_MAC_RCV_GOOD_UCAST = 0,
    SYS_STATS_MAC_RCV_GOOD_MCAST = 1,
    SYS_STATS_MAC_RCV_GOOD_BCAST = 2,
    SYS_STATS_MAC_RCV_GOOD_NORMAL_PAUSE = 3,
    SYS_STATS_MAC_RCV_GOOD_PFC_PAUSE = 4,
    SYS_STATS_MAC_RCV_GOOD_CONTROL = 5,
    SYS_STATS_MAC_RCV_FCS_ERROR = 6,
    SYS_STATS_MAC_RCV_MAC_OVERRUN = 7,
    SYS_STATS_MAC_RCV_GOOD_63B = 8,
    SYS_STATS_MAC_RCV_BAD_63B = 9,
    SYS_STATS_MAC_RCV_GOOD_MTU1_TO_MTU2 = 10,
    SYS_STATS_MAC_RCV_BAD_MTU1_TO_MTU2 = 11,
    SYS_STATS_MAC_RCV_GOOD_JUMBO = 12,
    SYS_STATS_MAC_RCV_BAD_JUMBO =13,
    SYS_STATS_MAC_RCV_64B = 14,
    SYS_STATS_MAC_RCV_127B = 15,
    SYS_STATS_MAC_RCV_255B = 16,
    SYS_STATS_MAC_RCV_511B = 17,
    SYS_STATS_MAC_RCV_1023B = 18,
    SYS_STATS_MAC_RCV_1518B = 19,
    SYS_STATS_MAC_RCV_2047B = 20,
    SYS_STATS_MAC_RCV_MTU1 = 21,

    SYS_STATS_MAC_RCV_NUM
};
typedef enum sys_stats_mac_rec_stats_type_e sys_stats_mac_rec_stats_type_t;

enum sys_stats_mac_snd_stats_type_e
{
    SYS_STATS_MAC_SEND_UCAST = 22,
    SYS_STATS_MAC_SEND_MCAST = 23,
    SYS_STATS_MAC_SEND_BCAST = 24,
    SYS_STATS_MAC_SEND_PAUSE = 25,
    SYS_STATS_MAC_SEND_CONTROL = 26,
    SYS_STATS_MAC_SEND_FCS_ERROR = 27,
    SYS_STATS_MAC_SEND_MAC_UNDERRUN = 28,
    SYS_STATS_MAC_SEND_63B = 29,
    SYS_STATS_MAC_SEND_64B = 30,
    SYS_STATS_MAC_SEND_127B = 31,
    SYS_STATS_MAC_SEND_255B =32,
    SYS_STATS_MAC_SEND_511B = 33,
    SYS_STATS_MAC_SEND_1023B = 34,
    SYS_STATS_MAC_SEND_1518B =35,
    SYS_STATS_MAC_SEND_2047B = 36,
    SYS_STATS_MAC_SEND_MTU1 = 37,
    SYS_STATS_MAC_SEND_MTU2 = 38,
    SYS_STATS_MAC_SEND_JUMBO = 39,

    SYS_STATS_MAC_STATS_TYPE_NUM = 40,
    SYS_STATS_MAC_SEND_NUM = SYS_STATS_MAC_STATS_TYPE_NUM-SYS_STATS_MAC_SEND_UCAST
};
typedef enum sys_stats_mac_snd_stats_type_e sys_stats_mac_snd_stats_type_t;

struct sys_usw_dmps_mac_stats_s
{
    uint64 rx_bytes[SYS_STATS_MAC_RCV_NUM];
    uint64 rx_pkts[SYS_STATS_MAC_RCV_NUM];
    uint64 tx_bytes[SYS_STATS_MAC_SEND_NUM];
    uint64 tx_pkts[SYS_STATS_MAC_SEND_NUM];
};
typedef struct sys_usw_dmps_mac_stats_s sys_usw_dmps_mac_stats_t;

struct sys_dmps_port_info_s
{
    uint8  dir_bmp;
    uint8  index;
    uint16 lport;
};
typedef struct sys_dmps_port_info_s sys_dmps_port_info_t;

struct sys_usw_dmps_serdes_id_s
{
    uint16 serdes[SYS_DMPS_MAX_SERDES_NUM_PER_PORT];
    uint8  num;
};
typedef struct sys_usw_dmps_serdes_id_s sys_usw_dmps_serdes_id_t;

struct cl73_ability_ctc_sys_map_tbl_s
{
    uint32  ctc_ability;
    uint32  sys_ability;
    uint32* p_ability;
};
typedef struct cl73_ability_ctc_sys_map_tbl_s cl73_ability_ctc_sys_map_tbl_t;

enum sys_usw_dmps_link_fsm_e
{
    PMA_RX_NONREADY        = 0,
    PMA_RX_PRE_TRAIN1      = 1,
    PMA_RX_PRE_TRAIN2      = 2,
    PMA_RX_PRE_TRAIN3      = 3,
    PMA_RX_PRE_TRAIN4      = 4,
    PMA_RX_PRE_TRAIN5      = 5,
    PMA_RX_PCS_SYNC1       = 6,
    PMA_RX_PCS_SYNC2       = 7,
    PMA_RX_POST_TRAIN1     = 8,
    PMA_RX_POST_TRAIN2     = 9,
    PMA_RX_POST_TRAIN3     = 10,
    PMA_RX_POST_TRAIN4     = 11,
    PMA_RX_TRAIN_DONE      = 12,
    PMA_RX_READY           = 13,
    PMA_RX_COVER           = 14,
    PMA_RX_ERROR           = 15,
};
typedef enum sys_usw_dmps_link_fsm_e sys_usw_dmps_link_fsm_t;

enum sys_usw_dmps_link_mode_e
{
    LINK_MODE_PCS_PMA,          /*pcs-pma linkup mode*/
    LINK_MODE_STDALONE,         /*standalone mode*/
    LINK_MODE_BUTT
};
typedef enum sys_usw_dmps_link_mode_e sys_usw_dmps_link_mode_t;

enum sys_usw_dmps_rx_train_stat_e
{
    RX_TRAIN_STOP,
    RX_TRAIN_RUN,
    RX_TRAIN_SUCCESS,
    RX_TRAIN_FAIL,
};
typedef enum sys_usw_dmps_rx_train_stat_e sys_usw_dmps_rx_train_stat_t;

enum sys_usw_dmps_rx_rst_condition_e
{
    RST_PCS_0_MAC_1,
    RST_PCS_1_MAC_1,
    RST_PCS_0_MAC_0,
    RST_COND_BUTT,
};
typedef enum sys_usw_dmps_rx_rst_condition_e sys_usw_dmps_rx_rst_condition_t;

enum sys_usw_dmps_lpbk_en_type_e
{
    DMPS_SERDES_LPBK_INTERNAL,
    DMPS_SERDES_LPBK_EXTERNAL,
    DMPS_SERDES_LPBK_LOCAL,
    DMPS_SERDES_LPBK_PCS,
    DMPS_SERDES_LPBK_NONE,
};
typedef enum sys_usw_dmps_lpbk_en_type_e sys_usw_dmps_lpbk_en_type_t;

enum sys_usw_dmps_serdes_eye_e
{
    DMPS_SERDES_EYE_WIDTH,
    DMPS_SERDES_EYE_HEIGHT,
};
typedef enum sys_usw_dmps_serdes_eye_e sys_usw_dmps_serdes_eye_t;

/****************************************************************************
 *
* Function
*
*****************************************************************************/
extern int32
sys_usw_dmps_gport_map_to_lport_with_check(uint8 lchip, uint32 gport, uint16* p_lport);
extern int32
sys_usw_dmps_get_interface_mode(uint8 lchip, uint16 lport, ctc_port_if_mode_t* if_mode);
extern int32
sys_usw_dmps_set_mac_capability(uint8 lchip, uint16 lport, ctc_port_capability_type_t type, uint32 value);
extern int32
sys_usw_dmps_get_mac_capability(uint8 lchip, uint16 lport, ctc_port_capability_type_t type, void* p_value);
extern int32
sys_usw_dmps_serdes_set_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value);
extern int32
sys_usw_dmps_serdes_get_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value);
extern int32
sys_usw_dmps_serdes_set_mode(uint8 lchip, ctc_chip_serdes_info_t* p_serdes_info);

extern int32
sys_usw_dmps_port_swap(uint8 lchip, uint16 src_lport, uint16 dst_lport);

extern int32
sys_usw_dmps_set_port_property(uint8 lchip, uint32 gport, uint8 dmps_port_prop, void *p_value);

extern int32
sys_usw_dmps_get_sfd_en(uint8 lchip, uint16 lport, uint32 *enable);

extern int32
sys_usw_dmps_get_port_property(uint8 lchip, sys_dmps_port_info_t* port_info, uint8 dmps_port_prop, void *p_value);


/* read table to get local phy port with channel */
extern uint16
sys_usw_dmps_get_lport_with_chan(uint8 lchip, uint8 dir, uint16 chan_id);
extern uint16
sys_usw_dmps_get_lport_with_subchan(uint8 lchip, uint8 sub_chan_id);
extern uint16 
sys_usw_dmps_get_lport_with_subchan_db(uint8 lchip, uint8 dir, uint8 core, uint8 pp, uint8 dp, uint8 sub_chan_id);

#if 1   /* will delete later */
extern uint16
sys_usw_dmps_get_lport_with_mac(uint8 lchip, uint16 mac_id);

extern uint16
sys_usw_dmps_get_lport_with_mac_tbl_id(uint8 lchip, uint16 mac_tbl_id);
#endif

extern uint16
sys_usw_dmps_get_core_clock(uint8 lchip, uint8 core_type);

extern int32
sys_usw_dmps_set_dlb_chan_type(uint8 lchip, uint16 chan_id);

extern int32
sys_dmps_get_sub_chan_by_chan(uint8 lchip, uint8 dir, uint16 chan, uint16* sub_chan, uint8* pp_id, uint8* dp_id);

extern int32
sys_usw_dmps_bpe_lport_map(uint8 lchip, uint32 gport, uint16 port_base, uint16 port_num, uint8 enable);

extern int32
sys_usw_dmps_get_flexe_aps(uint8 lchip, uint16 lport, uint8* p_enable, uint32* p_mac_aps);

extern int32
sys_usw_dmps_set_mac_property(uint8 lchip, uint16 lport, ctc_port_property_t port_prop,  uint32 value);

extern int32
sys_usw_dmps_get_mac_property(uint8 lchip, uint16 lport, ctc_port_property_t port_prop,  uint32* p_value);

extern int32
sys_usw_dmps_port_get_link_info(uint8 lchip, uint16 lport, void* p_value);

extern int32
sys_usw_dmps_port_check_datapath_credit_clear(uint8 lchip, uint32 mac_id, uint32 chan_id);

extern int32
sys_usw_dmps_port_set_other_misc_chan(uint8 lchip, uint16 lport, uint8 port_type, uint8 speed_mode, uint8 dir_bmp);

extern int32
sys_usw_dmps_get_internal_chan_start(uint8 lchip, uint8 dp_id, uint16* p_chan_id);

extern int32
sys_usw_dmps_port_set_link_info(uint8 lchip, uint16 lport, void* p_value);

extern int32
sys_usw_dmps_mac_set_interface_mode(uint8 lchip, uint16 lport, ctc_port_if_mode_t* if_mode);

extern int32
sys_usw_dmps_init(uint8 lchip, ctc_port_global_cfg_t* p_port_global_cfg);

extern int32
sys_usw_dmps_deinit(uint8 lchip);

extern int32
_sys_usw_dmps_set_mac_en(uint8 lchip, uint16 lport, uint32 enable, uint8 db_upt_flag);
    
extern int32
_sys_usw_dmps_set_fec(uint8 lchip, uint16 lport, uint32 value);
extern int32
_sys_usw_dmps_set_flush_en(uint8 lchip, uint16 lport, uint8 enable);
extern int32
_sys_usw_dmps_set_speed(uint8 lchip, uint16 lport, uint32 value);
extern int32
_sys_usw_dmps_get_sgmii_speed(uint8 lchip, uint16 lport, uint32* p_value);

extern int32
sys_usw_dmps_set_mac_property_dispatch(uint8 lchip, uint16 lport, ctc_port_property_t port_prop,  uint32 value);
extern int32
sys_usw_dmps_get_mac_property_dispatch(uint8 lchip, uint16 lport, ctc_port_property_t port_prop, uint32* p_value);
extern int32
_sys_usw_dmps_get_daemon_en(uint8 lchip, uint32* p_value);
extern int32
_sys_usw_dmps_set_daemon_en(uint8 lchip, uint32 value);
extern int32
_sys_usw_dmps_get_daemon_gap_ms(uint8 lchip, uint32* p_value);
extern int32
_sys_usw_dmps_set_daemon_gap_ms(uint8 lchip, uint32 value);
extern uint32
sys_usw_dmps_get_speed_from_serdes_info(uint8 if_mode, uint8 fec_type, uint8 ocs);
extern int32
_sys_usw_dmps_dynamic_switch_serdes_get_list(uint8 lchip, ctc_chip_serdes_info_t* p_serdes_info, 
                                                            sys_dmps_ds_list_t* p_list);
extern int32
_sys_usw_dmps_dynamic_switch_get_list(uint8 lchip, uint16 lport, ctc_port_if_mode_t* if_mode, 
                                                  sys_dmps_ds_list_t* p_list);
extern int32
_sys_usw_dmps_dynamic_switch_set_property_clear(uint8 lchip, sys_dmps_ds_list_t* p_list, uint32 option_bmp);
extern int32
_sys_usw_dmps_dynamic_switch_set_config(uint8 lchip, sys_dmps_ds_list_t* p_list, uint32 option_bmp);
extern int32
sys_usw_dmps_link_up_event(uint8 lchip, uint16 lport);
extern int32
sys_usw_dmps_link_down_event(uint8 lchip, uint16 lport);

/* ANLT SM */
extern int32
sys_usw_dmps_anlt_sm_send_anlt_en_msg(uint8 lchip, uint16 dport);
extern int32
sys_usw_dmps_anlt_sm_send_switch_off_msg(uint8 lchip, uint16 dport);
extern int32
sys_usw_dmps_anlt_sm_send_an_fec_msg(uint8 lchip, uint16 dport);
extern int32
sys_usw_dmps_anlt_sm_send_fec_type_msg(uint8 lchip, uint16 dport);
extern int32
sys_usw_dmps_anlt_sm_cl73_en_event(uint8 lchip, uint16 dport, uint8 enable);
extern int32
sys_usw_dmps_anlt_sm_register_msg(uint8 lchip);
extern int32
sys_usw_dmps_anlt_sm_send_restart_an_msg(uint8 lchip, uint16 dport);
extern int32
sys_usw_dmps_anlt_sm_send_link_down_msg(uint8 lchip, uint16 dport, uint8 pcs_status);
extern int32
_sys_usw_dmps_get_an_en(uint8 lchip, uint16 lport, uint32* p_value);
extern int32
_sys_usw_dmps_get_mac_link_up(uint8 lchip, uint16 lport, uint32* p_is_up, uint32 is_port);
extern int32
_sys_usw_dmps_mac_isr_dispatch(uint8 lchip, uint32 intr, void* p_data, uint8* p_link_intr, ctc_port_link_status_t* port_link_status);
extern int32
_sys_usw_dmps_cpumac_isr_dispatch(uint8 lchip, uint32 intr, void* p_data, uint8* p_link_intr, ctc_port_link_status_t* port_link_status);
extern void
sys_usw_dmps_daemon_thread(uint8 lchip, uint16 lport);

/*DMPS MSG*/
extern int32
sys_usw_dmps_msg_init(uint8 lchip, void* p_data);
extern int32 
sys_usw_dmps_msg_sync_send(uint8 lchip, uint8 mcu_id, uint32 msg_type, uint32 data_len, void* p_in, void* p_out);
extern int32 
sys_usw_dmps_msg_send(uint8 lchip, uint8 mcu_id, uint32 msg_type, uint32 data_len, void* p_in);
extern int32
sys_usw_dmps_msg_recv(uint8 lchip, uint8 mcu_id);
extern int32
_sys_usw_dmps_msg_register_rx_cb(uint8 lchip, uint32 msg_type, uint8 rps_data_size, void* recv_cb);
extern int32
_sys_usw_dmps_msg_register_tx_pri(uint8 lchip, uint32 msg_type, uint32 priority);


extern int32
sys_usw_dmps_get_mac_stats(uint8 lchip, uint32 block_id, sys_usw_dmps_mac_stats_t* p_mac_stats);
extern int32
sys_usw_dmps_clear_mac_stats(uint8 lchip, uint32 block_id, uint8 dir);
extern int32
_sys_usw_dmps_reset_hw_datapath_proc(uint8 lchip, void* p_data);

extern int32
sys_usw_dmps_port_set_err_inject(uint8 lchip, uint16 lport, void* p_value);
extern int32
sys_usw_dmps_port_get_err_inject(uint8 lchip, uint16 lport, void* p_value);
extern int32
sys_usw_dmps_port_set_cl73_ability_ext(uint8 lchip, uint16 lport, void* p_value);
extern int32
_sys_usw_dmps_reset_hw_port_attr_restore(uint8 lchip, void* p_port_attr);
extern int32
_sys_usw_dmps_reset_hw_port_attr_recover(uint8 lchip, void* p_port_attr);
extern void
_sys_usw_dmps_reset_hw_clear_link_fsm(uint8 lchip);
#ifdef __cplusplus
}
#endif

#endif

